package com.whf.android.jar.net.download;

import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.blankj.utilcode.util.AppUtils;
import com.whf.android.jar.app.Latte;
import com.whf.android.jar.net.HttpCode;
import com.whf.android.jar.net.callback.IError;
import com.whf.android.jar.net.callback.IRequest;
import com.whf.android.jar.net.callback.ISuccess;
import com.whf.android.jar.util.file.FileUtil;
import com.whf.android.jar.util.log.LatteLogger;

import java.io.File;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;

import okhttp3.ResponseBody;

/**
 * 下载的处理
 *
 * @author 傅令杰
 * @date 2017/4/2
 */
final class SaveFileTask implements IAsyncTask {

    private final static String INSTALL = "apk";

    private final IRequest REQUEST;
    private final ISuccess SUCCESS;
    private final IError ERROR;
    private final ResponseBody responseBody;
    private final String DOWNLOAD_DIR, EXTENSION, NAME;

    public SaveFileTask(IRequest request, ISuccess success, IError error, ResponseBody body,
                        String downloadDir, String extension, String name) {
        this.REQUEST = request;
        this.SUCCESS = success;
        this.ERROR = error;
        this.responseBody = body;
        this.DOWNLOAD_DIR = downloadDir;
        this.EXTENSION = extension;
        this.NAME = name;
    }

    @Override
    @RequiresApi(api = Build.VERSION_CODES.N)
    public void executeOnExecutor() {
        // 执行耗时操作
        CompletableFuture
                .supplyAsync(this::doInBackground)
                .thenApply(file -> {
                    // 在主线程中执行完成后的操作
                    onPostExecute(file);
                    return file;
                }).exceptionally(throwable -> {
                    // 异常处理
                    onExceptionally(throwable);
                    return null;
                });
    }

    /**
     * 执行耗时操作
     */
    @Nullable
    @Override
    public File doInBackground() {
        // 后台执行文件保存操作
        try {
            String downloadDir = DOWNLOAD_DIR;
            String extension = EXTENSION;
            String name = NAME;
            if (downloadDir == null || downloadDir.isEmpty()) {
                downloadDir = "down_loads";
            }
            if (extension == null || extension.isEmpty()) {
                extension = "";
            }

            final InputStream is = responseBody.byteStream();
            final long total = responseBody.contentLength();

            if (name == null) {
                return FileUtil.writeToDisk(is, downloadDir, REQUEST, total,
                        extension.toUpperCase(), extension);
            } else {
                return FileUtil.writeToDisk(is, downloadDir, REQUEST, total, name);
            }
        } catch (Exception e) {
            LatteLogger.e("Download failed: " + e.getMessage());
            return null;
        }
    }

    /**
     * 耗时操作完成后的操作
     *
     * @param file:
     */
    @Override
    public void onPostExecute(File file) {
        LatteLogger.i("下载完成,开始回调");
        Latte.getHandler().post(() -> {
            if (file != null) {
                LatteLogger.i("主线程中执行完成后的操作", file.getPath());
                if (SUCCESS != null) {
                    SUCCESS.onSuccess(file.getPath());
                }
                // 处理 APK 安装
                installApp(file);
            }
            if (REQUEST != null) {
                REQUEST.onRequestEnd();
            }
        });
    }

    @Override
    public void onExceptionally(Throwable throwable) {
        // 异常处理
        Latte.getHandler().post(() -> {
            if (ERROR != null) {
                ERROR.onError(HttpCode.CODE__1, "Download failed: " + throwable.getMessage());
            }
            if (REQUEST != null) {
                REQUEST.onRequestEnd();
            }
        });
    }

    /**
     * 如果是那想类型的,操作
     *
     * @param file:文件
     */
    private void installApp(@NonNull File file) {
        LatteLogger.i("installApp", file.getPath());
        if (INSTALL.equals(FileUtil.getExtension(file.getPath()))
                || "apk".equalsIgnoreCase(EXTENSION)) {
            LatteLogger.i("开始安装app", file.getPath());
            AppUtils.installApp(file);
        }
    }

}
